package com.hnn;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @author hnn
 * @version 1.0
 * @date 2024-03-21 10:31
 */
public class MultiPlexNioServer {

    static Selector selector;

    private static void acceptHandler(SelectionKey key) throws IOException {
        ServerSocketChannel socketChannelServer = (ServerSocketChannel)key.channel();
        SocketChannel client =  socketChannelServer.accept();
        client.configureBlocking(false);
        ByteBuffer buff = ByteBuffer.allocate(4096);
        client.register(selector, SelectionKey.OP_READ, buff);
    }

    private static void readHandler(SelectionKey key) throws IOException {
        ByteBuffer buff = (ByteBuffer) key.attachment();
        SocketChannel client = (SocketChannel) key.channel();
        buff.clear();
        while (true) {
            int r = client.read(buff);
            if (r > 0) {
                buff.flip();
                byte[] b=new byte[r];
                buff.get(b);
                String str = new String(b);
                System.out.printf("------->接收:%s%n", str);
                client.write(buff);
            } else if (r == 0) {
                break;
            } else {
                client.close();
            }
        }

    }

    public static void main(String[] args) throws Exception {
        selector = Selector.open();
        ServerSocketChannel socketChannelServer = ServerSocketChannel.open();
        socketChannelServer.configureBlocking(false);
        socketChannelServer.bind(new InetSocketAddress(17777));
        socketChannelServer.register(selector, SelectionKey.OP_ACCEPT);
        ByteBuffer buff = ByteBuffer.allocate(4096);

        while (true) {
            if (selector.select(0) > 0) {
                Set<SelectionKey> keys = selector.selectedKeys();
                Iterator<SelectionKey> keyIterator = keys.iterator();
                while (keyIterator.hasNext()) {
                    SelectionKey key = keyIterator.next();
                    keys.remove(key);

                    if (key.isAcceptable()) {
                        acceptHandler(key);
                    } else if (key.isReadable()) {
                        readHandler(key);
                    }
                }
            }
        }
    }
}
